package com.dews.train.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dews.common.exception.ServiceException;
import com.dews.information.domain.entity.SubjectCourse;
import com.dews.information.mapper.SubjectCourseMapper;
import com.dews.train.convert.ProgramTeachPlanConvert;
import com.dews.train.domain.entity.ProgramTeachPlan;
import com.dews.train.domain.entity.TrainingProgram;
import com.dews.train.domain.vo.ProgramTeachPlanVo;
import com.dews.train.mapper.ProgramTeachPlanMapper;
import com.dews.train.mapper.TrainingProgramMapper;
import com.dews.train.service.IProgramTeachPlanService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 方案教学计划Service业务层处理
 *
 * @author qingfeng
 * @date 2024-12-22
 */
@Service
public class ProgramTeachPlanServiceImpl extends ServiceImpl<ProgramTeachPlanMapper, ProgramTeachPlan> implements IProgramTeachPlanService {

    private ProgramTeachPlanMapper programTeachPlanMapper;
    private SubjectCourseMapper subjectCourseMapper;
    private TrainingProgramMapper trainingProgramMapper;

    @Autowired
    public ProgramTeachPlanServiceImpl(ProgramTeachPlanMapper programTeachPlanMapper,
                                       SubjectCourseMapper subjectCourseMapper,
                                       TrainingProgramMapper trainingProgramMapper) {
        this.programTeachPlanMapper = programTeachPlanMapper;
        this.subjectCourseMapper = subjectCourseMapper;
        this.trainingProgramMapper = trainingProgramMapper;
    }

    /**
     * 查询方案教学计划列表
     *
     * @param programId 方案教学计划
     * @return 方案教学计划
     */
    @Override
    public List<ProgramTeachPlanVo> selectProgramTeachPlanList(Integer programId) {
        // 查询方案下所有的教学计划
        List<ProgramTeachPlan> programTeachPlanList = programTeachPlanMapper.selectList(
                new LambdaQueryWrapper<ProgramTeachPlan>()
                        .eq(ProgramTeachPlan::getProgramId, programId)
        );
        if (CollUtil.isEmpty(programTeachPlanList)) {
            return Collections.emptyList();
        }

        Map<Integer, SubjectCourse> subjectCourseMap = subjectCourseMapper.selectList(
                        new LambdaQueryWrapper<SubjectCourse>()
                                .in(SubjectCourse::getId, programTeachPlanList.stream().map(ProgramTeachPlan::getCourseId).collect(Collectors.toSet()))
                )
                .stream()
                .collect(Collectors.toMap(
                        SubjectCourse::getId,
                        Function.identity()
                ));

        List<ProgramTeachPlanVo> programTeachPlanVoList = new ArrayList<>();
        programTeachPlanList.stream()
                .collect(Collectors.groupingBy(ProgramTeachPlan::getCoursePlatform))
                .values()
                .stream()
                .forEach(v -> {
                    // 按主模块分组
                    v.stream()
                            .collect(Collectors.groupingBy(ProgramTeachPlan::getCourseMainModule))
                            .values()
                            .stream()
                            .forEach(m -> {
                                // 按子模块分组
                                m.stream()
                                        .collect(Collectors.groupingBy(ProgramTeachPlan::getCourseChildrenModule))
                                        .values()
                                        .stream()
                                        .forEach(c -> {
                                            // 按修读要求分组
                                            c.stream()
                                                    .collect(Collectors.groupingBy(ProgramTeachPlan::getStudyRequire))
                                                    .values()
                                                    .stream()
                                                    .forEach(s -> {
                                                        // 按学期分组
                                                        s.forEach(o -> {
                                                            ProgramTeachPlanVo programTeachPlanVo = ProgramTeachPlanConvert.INSTANCE.convert(o);
                                                            programTeachPlanVo.setCourseCode(subjectCourseMap.get(o.getCourseId()).getCourseCode());
                                                            programTeachPlanVo.setCourseName(subjectCourseMap.get(o.getCourseId()).getCourseName());
                                                            // 多个学期处理成字符串
                                                            if (programTeachPlanVo.getSemester().size() > 1) {
                                                                List<Integer> collect = programTeachPlanVo.getSemester().stream().sorted().collect(Collectors.toList());
                                                                programTeachPlanVo.setSemesterStr(collect.get(0) + "-" + collect.get(collect.size() - 1));
                                                                programTeachPlanVo.setCreditComputed(programTeachPlanVo.getCredit().toString() + "*" + programTeachPlanVo.getSemester().size());
                                                            } else {
                                                                programTeachPlanVo.setSemesterStr(String.valueOf(programTeachPlanVo.getSemester().get(0)));
                                                                programTeachPlanVo.setCreditComputed(programTeachPlanVo.getCredit().toString());
                                                            }
                                                            programTeachPlanVoList.add(programTeachPlanVo);
                                                        });
                                                    });
                                            // 子模块分组统计完成之后，需要计算小计
                                        });
                            });
                });

        return programTeachPlanVoList;
    }

    /**
     * 查询方案教学计划
     *
     * @param id 方案教学计划主键
     * @return 方案教学计划
     */
    @Override
    public ProgramTeachPlan selectProgramTeachPlanById(Integer id) {
        return baseMapper.selectById(id);
    }

    /**
     * 新增方案教学计划
     *
     * @param programTeachPlanVo 方案教学计划
     * @return 结果
     */
    @Override
    public int insertProgramTeachPlan(ProgramTeachPlanVo programTeachPlanVo) {
        // 课程不应该有重复的
        if (programTeachPlanMapper.selectCount(
                new LambdaQueryWrapper<ProgramTeachPlan>()
                        .eq(ProgramTeachPlan::getProgramId, programTeachPlanVo.getProgramId())
                        .eq(ProgramTeachPlan::getCourseId, programTeachPlanVo.getCourseId())
        ) > 0) {
            throw new ServiceException("方案中已经存在该课程，请勿重复添加");
        }
        ProgramTeachPlan programTeachPlan = ProgramTeachPlanConvert.INSTANCE.convert(programTeachPlanVo);
        return programTeachPlanMapper.insert(programTeachPlan);

    }

    /**
     * 修改方案教学计划
     *
     * @param programTeachPlanVo 方案教学计划
     * @return 结果
     */
    @Override
    public int updateProgramTeachPlan(ProgramTeachPlanVo programTeachPlanVo) {
        // 课程不应该重复
        if (programTeachPlanMapper.selectCount(
                new LambdaQueryWrapper<ProgramTeachPlan>()
                        .eq(ProgramTeachPlan::getProgramId, programTeachPlanVo.getProgramId())
                        .eq(ProgramTeachPlan::getCourseId, programTeachPlanVo.getCourseId())
                        .ne(ProgramTeachPlan::getId, programTeachPlanVo.getId())
        ) > 0) {
            throw new ServiceException("方案中已经存在该课程，请勿重复添加");
        }
        ProgramTeachPlan programTeachPlan = ProgramTeachPlanConvert.INSTANCE.convert(programTeachPlanVo);
        return programTeachPlanMapper.updateById(programTeachPlan);
    }

    /**
     * 批量删除方案教学计划
     *
     * @param ids 需要删除的方案教学计划主键
     * @return 结果
     */
    @Override
    public int deleteProgramTeachPlanByIds(List<Integer> ids) {
        return programTeachPlanMapper.deleteBatchIds(ids);
    }


    @Override
    public List<SubjectCourse> getCourseListByProgramId(Integer programId) {
        TrainingProgram trainingProgram = trainingProgramMapper.selectById(programId);
        if (ObjectUtil.isEmpty(trainingProgram)) {
            throw new ServiceException("方案不存在");
        }
        return subjectCourseMapper.selectList(
                new LambdaQueryWrapper<SubjectCourse>()
                        .eq(SubjectCourse::getDepId, trainingProgram.getDepId())
                        .eq(SubjectCourse::getSubjectId, trainingProgram.getSubjectId())
                        .eq(SubjectCourse::getIsEnable, 1)
        );

    }

}
